//
//  YRServer.swift
//  YRProject
//
//  Created by 薛永伟 on 2019/10/15.
//  Copyright © 2019 XueYongWei. All rights reserved.
//

import Foundation
import Alamofire

class YRServer:NSObject {
    
    /// header里返回的token
    static var headerTokenKey = "x-auth-token"
    
    
    /// 请求完毕
    typealias CompleteBlock = (_ response:Response)->()
    
    /// 远程服务出错
    struct ServiceError:Error,LocalizedError,Decodable {
        /// 错误码
        var code:Int
        /// 错误信息
        var errorMessage:String
    }
    
    /// 回应数据
    struct Response:Decodable {
        
        /// 需要解析的原始结构数据
        var data:JSON
        /// server返回的状态码
        var code:Int = 0
        /// 信息
        var message:String = ""
        /// 错误（已封装的错误）
        var error:ServiceError?
    }
    
}

extension YRServer {
    
    /// 发起请求
    @discardableResult
    static func request(_ url: URLConvertible,
                        method:HTTPMethod = .post,
                        headers:HTTPHeaders? = nil,
                        parameters: Parameters? = nil
        ) -> DataRequest{
        
        
        YRLog("发起请求:\(url)\n\(parameters?.description ?? "无参数")\n")
        return SessionManager.default.request(
            url,
            method: method,
            parameters: parameters,
            encoding: URLEncoding.default,
            headers: headers
        )
    }
    
    static func upload(data:Data,to url:URL,method:HTTPMethod,headers:HTTPHeaders?) -> UploadRequest {
        
        return SessionManager.default.upload(data, to: url, method: method, headers: headers)
    }
    
    
    static func uploadPictures(_ url: URLConvertible,
                               method:HTTPMethod = .post,
                               parameters: [String:String]? = nil,
                               headers:HTTPHeaders? = nil,
                               pictures:[UIImage],
                               pictureNames:[String],
                               complete:@escaping (SessionManager.MultipartFormDataEncodingResult)->()) {
        
        
        SessionManager.default.upload(multipartFormData: { (formData) in
            
            for (idx,pic) in pictures.enumerated() {
                if let picData = pic.compressImageOnlength(maxLength: 500){
                    formData.append(picData, withName: pictureNames[idx], fileName: "pic\(idx).jpg", mimeType: "image/jpeg")
                }
            }
            
            if let params = parameters {
                for (key,value) in params {
                    if let valueData = value.data(using: String.Encoding.utf8){
                        formData.append(valueData, withName: key)
                    }
                }
            }
        }, to: url, method:method , headers: headers) { (formDataEncodingResult) in
            
            complete(formDataEncodingResult)
            
        }
        
    }
}

//MARK: - --------------DataRequest--------------
extension DataRequest {
    
    /// 服务器返回的数据进行判断验证及封装
    ///
    /// - Parameters:
    ///   - verifykey: 验证请求是否成功的字段名
    ///   - verifyValue: 表示成功的值
    ///   - messageKey: message的字段名
    ///   - errorMessageKey: 错误信息的字段名
    ///   - authDeniedCode: 认证失败，可自定义操作
    ///   - complete: 完成回调
    /// - Returns: 当前response
    @discardableResult
    func yrResponse(verifykey:String = "code",
                        verifyValue:Int? = nil,
                        messageKey:String = "message",
                        errorMessageKey:String = "errMsg",
                        authDeniedCode:Int? = nil,
                        complete:@escaping YRServer.CompleteBlock) -> Self {
        
        let requestLog = "->请求:\(request?.url?.absoluteString ?? "⚠️ 空的url地址")"
        
        let res = responseJSON { (response) in
            
            if let token = response.response?.allHeaderFields[YRServer.headerTokenKey] as? String {
                YRLog("得到token:\(token)", type: .info)
                YRAPI.Cookie.addTokenCookie(token: token, in: response.response?.url)
            }
            
            switch response.result{
            case .success(let value):
                let json = JSON(value)
                
                YRLog("\(requestLog)\n  成功:\n \(json) \n<-\n", type: .info)
                
                // 返回的code
                let responseCode = json[verifykey].intValue
                // 返回的message
                let message = json[messageKey].stringValue
                
                // 是否有错误
                var error:YRServer.ServiceError? = nil
                
                if let verifyCode = verifyValue,
                    verifyCode != responseCode {//如果需要验证返回码，直接验证，不一致就返回错误信息
                    
                    let errorMessage = json[errorMessageKey].string ?? "出错了"
                    
                    error = YRServer.ServiceError.init(code: responseCode, errorMessage: errorMessage)
                    
                    if let authCode = authDeniedCode,authCode == responseCode {
                        YRLog("认证失败！code = \(responseCode)", type: .error)
                    }
                }
                
                let response = YRServer.Response.init(data: json, code: responseCode, message: message, error: error)
                complete(response)
                
                break
            case .failure(let error):
                
                let nserror = error as NSError
                
                var error = YRServer.ServiceError.init(code: nserror.code, errorMessage: nserror.localizedDescription)
                if error.code == -1009 {
                    error.errorMessage = "网络连接状态异常，请检查"
                }
                
                YRLog("\(requestLog)\n 失败:\n \(error.localizedDescription) \n<-\n", type: .info)
                
                let response = YRServer.Response.init(data: JSON(), code: 1, message: "", error: error)
                complete(response)
                break
            }
        }
        return res
    }
    
    
}
